#ifndef VTKMESHIMPORT_HPP
#define VTKMESHIMPORT_HPP

#include "meshTypes_fwd.hpp"
#include "tinyxml2.h"
#include <iostream>

#include <filesystem>

namespace hms::vtk {

namespace fs = std::filesystem;
namespace xml = tinyxml2;

/**
 * @brief Deduces the mesh type from the file extension
 * 
 * @return MeshVariant 
 */
MeshVariant extensionToMeshType( const fs::path& );

/**
 * @brief Takes the domain/mesh and boundary documents and a MeshVariant that
 * must already have the correct type, and reads the mesh data from it.
 * 
 * @param domainDoc The VTK xml file
 * @param boundaryDoc 
 * @param meshVar 
 */
void toMesh(
	const xml::XMLDocument* domainDoc,
	const xml::XMLDocument* boundaryDoc,
	MeshVariant& meshVar
);

/**
 * @brief Takes an XML document and creates a mesh from it, whose type is
 * determined by the type held by the passed in hms::MeshVariant&
 * 
 * @return hms::MeshVariant& 
 */
void toMesh( const xml::XMLDocument*, MeshVariant& );

template<typename MeshType>
MeshType toMesh( const xml::XMLElement* );

/* these are called by toMesh(ostream&,MeshVariant&) depending on the mesh type
 * passed in */
template<>
Mesh  toMesh<Mesh>( const xml::XMLElement* );
template<>
UniMesh toMesh<UniMesh>( const xml::XMLElement* );
template<>
RectMesh  toMesh<RectMesh>( const xml::XMLElement* );
template<>
StructMesh  toMesh<StructMesh>( const xml::XMLElement* );

void readBoundaryPatches( const xml::XMLNode*, MeshVariant& );
void readBoundaryPatches( const fs::path&, MeshVariant& );

}

#endif